#pragma once
#ifndef __LIT__META__GROUP__INCLUDED__HH__
#define __LIT__META__GROUP__INCLUDED__HH__

#include <LitExceptions.h>
#include <LitPrerequisites.h>
#include <LitSerialiser.hpp>
#include <LitMetaData.h>

namespace Lit
{
	class LIT_API MetaGroup : public Named<true>
	{
		/*friend std::ostream& operator << ( std::ostream & strm, const MetaGroup& g );
		friend std::ostream& operator << ( std::ostream & strm, const MetaObject& g );
		friend std::istream& operator >> ( std::istream & strm, MetaGroup& g );
		friend std::istream& operator >> ( std::istream & strm, MetaObject& o );*/
	public:
		typedef std::unordered_map<String,MetaData> Map;

	protected:
		Map mProps;
		MetaObject * mParent;
	public:
		MetaGroup( MetaObject * parent = NULL, const String &name = "" );
		MetaGroup( const MetaGroup& rk );
		MetaGroup& operator=( const MetaGroup& rk );
		virtual ~MetaGroup();

		void setParent( MetaObject* parent );
		const MetaObject* parent () const;
		MetaObject* parent ();

		void merge( const MetaGroup& rk, bool replace_old = true );
		MetaData& operator[]( const String &name );

		Map::iterator find( const String &key );
		Map::const_iterator find( const String &key ) const;
		
		Map::iterator begin();
		Map::iterator end();

		Map::const_iterator begin() const;
		Map::const_iterator end() const;

		bool hasKey( const String &name ) const;
		
		void setProperty( const MetaData& d );
		void setProperty( const String &name, const String & val = "" );

		template<typename T> T getProperty( const String &name, const T &def_val = T() ) const
		{
			if( !hasKey( name ) ) return def_val;
			return mProps.at(name).to<T>(def_val);
		}

		void clear(){ mProps.clear(); }
		bool empty() const{ return mProps.empty(); }
		size_t size() const{ return mProps.size(); }
	};
	
};

#endif